#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_LEN 128

/* 函数原型 */
int CheckLuhn ( const char * cardId, int sum[2] );
int ReadLine(char *s);

int main()
{
    int s[2]={0}, r;
    char id[MAX_LEN];

    while (ReadLine(id) > 0) {
        r = CheckLuhn(id, s);
        printf("%s,R=%d\t%d\t%d\n", id, r, s[0], s[1]);
    }
    return 0;
}

/* 字符串读取 */
int ReadLine(char *s)
{
    int n = 0, ch = 0;
    while((ch = getchar()) != '\n' && ch != EOF && n <= MAX_LEN - 1)
        s[n++] = ch;
    s[n]='\0';
    return n;
}

/* Luhn模10校验 */
int CheckLuhn(const char * cardId, int sum[2])
{
    int i, j, len;
    char *s, *s_even, *s_odd;
    int even_flag;
    /* 偶数位计算结果查找表 */
    int even_lut[] = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};

    len = strlen(cardId);

    /* 创建偶数位辅助字符串 */
    s_even = malloc(len * sizeof(char));
    memset(s_even, 0, len * sizeof(char));
    /* 创建奇数位辅助字符串 */
    s_odd = malloc(len * sizeof(char));
    memset(s_odd, 0, len * sizeof(char));

    even_flag = (len & 1) ? 0 : 1;

    /* 遍历证件号码字符串分别提取奇数位和偶数位到辅助串 */
    i = 0;
    j = 0;
    while(*cardId)
    {
        if(!even_flag)
        {
            s_odd[i] = *cardId;
            i++;
        }
        else
        {
            s_even[j] = *cardId;
            j++;
        }

        even_flag = !even_flag;
        cardId++;
    }

    /* 结果累加器清0(非常重要) */
    sum[0] = 0;
    s = s_odd;
    /* 遍历奇数位辅助字符串实现计算 */
    while(*s)
    {
        sum[0] += *s & 0x0F;
        s++;
    }
    /* 释放空间 */
    free(s_odd);

    /* 结果累加器清0(非常重要) */
    sum[1] = 0;
    s = s_even;
    /* 遍历偶数位辅助字符串实现计算 */
    while(*s)
    {
        sum[1] += even_lut[*s & 0x0F]; /* 查找表实现 */
        s++;
    }
    /* 释放空间 */
    free(s_even);

    /* 校验并返回 */
    return ((sum[0] + sum[1]) % 10) ? 1 : 0;
}

